# -*- coding: utf-8 -*-
# @Time: 2021/11/11 17:09
# @Author: lijinxi
# @File    : generate_traces.py
# @desc

# 处理数据集,获取出租车轨迹
import os
from datetime import datetime
import numpy as np


class Preprocess(object):
    def __init__(self, path='../traces/gps_20161105'):
        self.dataset_path = path

        self.center_longitude = 0
        self.center_latitude = 0

        # 时隙共20个
        self.time_index = 0
        self.minutes = 0 * 60  # 从7点开始

        self.traces = dict()

        self.requests_matrix = np.zeros((20, 5, 5), dtype=np.int64)
        # 经纬度变化范围
        self.latitude_range = None
        self.longitude_range = None
        # 选中的范围
        # 计算1km的相差经纬度
        self.diff = 60 / 100  # 大约1km相差的经纬度,即0.6分
        self.select_latitude = None
        self.select_longitude = None

    # 了解大致数据分布
    def summary_data(self):
        max_latitude, min_latitude = 0, 10000
        max_longitude, min_longitude = 0, 10000
        with open(self.dataset_path, 'r', encoding='utf-8') as f:
            for line in f:
                taxi_id, order, timestamp, longitude, latitude = line.strip('\n').split(',')
                longitude, latitude = int(float(longitude) * 60), int(float(latitude) * 60)
                max_longitude = longitude if longitude > max_longitude else max_longitude
                min_longitude = longitude if longitude < min_longitude else min_longitude
                max_latitude = latitude if latitude > max_latitude else max_latitude
                min_latitude = latitude if latitude < min_latitude else min_latitude
                self.traces[taxi_id] = ''
        self.latitude_range = [min_latitude, max_latitude]
        self.longitude_range = [min_longitude, max_longitude]
        self.center_latitude = (self.latitude_range[0] + self.latitude_range[1]) / 2.0
        self.center_longitude = (self.longitude_range[0] + self.longitude_range[1]) / 2.0
        self.select_latitude = [self.center_latitude - self.diff * 2.5, self.center_latitude + self.diff * 2.5]
        self.select_longitude = [self.center_longitude - self.diff * 2.5, self.center_longitude + self.diff * 2.5]
        print(self.longitude_range, self.latitude_range, len(self.traces))

    def fetch_data(self, num=200):
        self.traces.clear()
        with open(self.dataset_path, 'r', encoding='utf-8') as f:
            for line in f:
                taxi_id, order, timestamp, longitude, latitude = line.strip('\n').split(',')
                longitude, latitude = int(float(longitude) * 60), int(float(latitude) * 60)
                x = int((longitude - self.select_longitude[0]) / self.diff)  # 落在哪一方格中
                y = int((latitude - self.select_latitude[0]) / self.diff)
                if self.valid_position(longitude, latitude):
                    if self.traces.get(taxi_id, None) is None:
                        self.traces[taxi_id] = []
                    if len(self.traces[taxi_id]) == 0:
                        self.traces[taxi_id].append((x, y))
                    else:
                        if (x, y) != self.traces[taxi_id][-1]:
                            self.traces[taxi_id].append((x, y))
        print(len(self.traces))
        new_trace = dict()
        count = 0
        for key, val in self.traces.items():
            if len(val) >= 26:
                count += 1
                new_trace[key] = val
                if count == num:
                    break
        print(len(new_trace))
        self.traces = new_trace

    def valid_time(self, timestamp, time_delta=2):  # 默认是10min
        # 校正是否是合适的时间
        d = datetime.fromtimestamp(float(timestamp))
        minutes = int(d.hour) * 60 + int(d.minute)
        return self.minutes + time_delta * self.time_index <= minutes <= self.minutes + time_delta * (
                self.time_index + 1)  # 判断时间是否在某一时隙内

    def valid_position(self, longitude, latitude):
        # 校正是否在合适的位置
        return self.select_longitude[0] <= longitude < self.select_longitude[1] and self.select_latitude[
            0] <= latitude < \
               self.select_latitude[1]

    def measure(self):
        for key, positions in self.traces.items():
            for i, (x, y) in enumerate(positions):
                if i == 20:
                    break
                self.requests_matrix[i][x][y] += 1
        # for i in range(0, 20):
        #     print(self.requests_matrix[i, :, :])
        print(self.requests_matrix[0, :, ])
        print(self.requests_matrix[0, :, ] - self.requests_matrix[1, :, ])

        # 将每一时刻的统计结果保存
        np.save('../traces/1/measure.npy', self.requests_matrix)

    def save_by_time(self):
        # 保存每一时刻的位置
        matrix_1 = None
        matrix_2 = None
        for i in range(20):
            matrix = np.zeros((len(self.traces), 25), dtype=np.int64)
            j = 0
            for key, positions in self.traces.items():
                x, y = positions[i]
                matrix[j][x * 5 + y] = 1
                j += 1
            if i == 0:
                matrix_1 = matrix
            if i == 1:
                matrix_2 = matrix
            np.save('time_slot_' + str(i) + '.npy', matrix)
        print(np.sum(np.multiply(matrix_1, matrix_2)))


if __name__ == '__main__':
    p = Preprocess()
    p.summary_data()
    p.fetch_data()
    p.measure()
    p.save_by_time()
